﻿Imports Microsoft.TeamFoundation
Imports Microsoft.TeamFoundation.Client
Imports Microsoft.TeamFoundation.WorkItemTracking.Client
Imports Microsoft.TeamFoundation.Framework.Client
Imports System.Net
Imports Microsoft.TeamFoundation.VersionControl.Client

Public Class WorkItemFileHistory

    Private findings As Dictionary(Of String, ItemHistory)

    Private Sub btnFindFiles_Click(sender As System.Object, e As System.EventArgs) Handles btnFindFiles.Click
        If moduleHost Is Nothing Then
            Throw New Exception("Module host can not set")
        End If

        Dim configurationServerUri As New Uri(moduleHost.GetServerAddress)

        Dim configurationServer As New TfsConfigurationServer(configurationServerUri, ModuleHost.GetCredentials())
        Dim tpcService As ITeamProjectCollectionService = configurationServer.GetService(Of ITeamProjectCollectionService)()
        Dim collections = tpcService.GetCollections()
        Dim collection As TfsTeamProjectCollection = configurationServer.GetTeamProjectCollection(collections(0).Id)
        Dim vcs As VersionControlServer = collection.GetService(GetType(VersionControlServer))


        Dim store As New WorkItemStore(collection)
        Dim wi = store.GetWorkItem(txtWorkItemID.Text)

        Dim associatedChangesets As New List(Of Changeset)
        For Each l As Link In wi.Links
            If l Is Nothing OrElse Not TypeOf (l) Is ExternalLink Then Continue For
            Dim actifact As ArtifactId = LinkingUtilities.DecodeUri(DirectCast(l, ExternalLink).LinkedArtifactUri)
            If Not actifact.ArtifactType = "Changeset" Then Continue For
            associatedChangesets.Add(vcs.ArtifactProvider.GetChangeset(New Uri(DirectCast(l, ExternalLink).LinkedArtifactUri)))
        Next

        Dim count As Integer = 0
        findings = New Dictionary(Of String, ItemHistory)
        For Each cs As Changeset In associatedChangesets
            count += 1
            For Each ch As Change In cs.Changes
                If findings.ContainsKey(ch.Item.ServerItem) Then
                    Dim hist As ItemHistory = findings(ch.Item.ServerItem)
                    If cs.ChangesetId < hist.FirstChangeset Then hist.FirstChangeset = cs.ChangesetId
                    If cs.ChangesetId > hist.LastChangeset Then hist.LastChangeset = cs.ChangesetId
                    hist.NumberOfTimesChanged += 1
                Else
                    Dim hist As New ItemHistory
                    hist.Item = ch.Item.ServerItem
                    hist.FirstChangeset = cs.ChangesetId
                    hist.LastChangeset = cs.ChangesetId
                    hist.NumberOfTimesChanged = 0
                    findings.Add(ch.Item.ServerItem, hist)
                End If
            Next
        Next

        ListBox1.DataSource = findings.ToList()
        MessageBox.Show(count.ToString + " files found")

    End Sub

    Private Sub btnExportFiles_Click(sender As System.Object, e As System.EventArgs) Handles btnExportFiles.Click
        If moduleHost Is Nothing Then
            Throw New Exception("Module host can not set")
        End If

        Dim configurationServerUri As New Uri(moduleHost.GetServerAddress)

        Dim configurationServer As New TfsConfigurationServer(configurationServerUri, _
                                                              CredentialCache.DefaultCredentials)
        Dim tpcService As ITeamProjectCollectionService = configurationServer.GetService(Of ITeamProjectCollectionService)()
        Dim collections = tpcService.GetCollections()
        Dim collection As TfsTeamProjectCollection = configurationServer.GetTeamProjectCollection(collections(0).Id)
        Dim vcs As VersionControlServer = collection.GetService(GetType(VersionControlServer))

        Dim hist As ItemHistory = ListBox1.SelectedItem.Value

        Dim newItem = vcs.GetItem(hist.Item, New ChangesetVersionSpec(hist.LastChangeset))
        If newItem IsNot Nothing AndAlso newItem.ItemType = ItemType.File Then
            Dim filename As String = newItem.ServerItem.Substring(newItem.ServerItem.LastIndexOf("/") + 1)
            newItem.DownloadFile(txtOutputFolder.Text + filename + "_" + hist.LastChangeset.ToString)
        End If

        Dim oldItem = vcs.GetItem(hist.Item, New ChangesetVersionSpec(hist.FirstChangeset - 1))
        If oldItem IsNot Nothing AndAlso oldItem.ItemType = ItemType.File Then
            Dim filename As String = oldItem.ServerItem.Substring(oldItem.ServerItem.LastIndexOf("/") + 1)
            oldItem.DownloadFile(txtOutputFolder.Text + filename + "_" + (hist.FirstChangeset - 1).ToString)
        End If

        MessageBox.Show("Files copied to " + txtOutputFolder.Text)
    End Sub

    Private Class ItemHistory
        Public Item As String
        Public FirstChangeset As Integer
        Public LastChangeset As Integer
        Public NumberOfTimesChanged As Integer

        Public Overrides Function ToString() As String
            Try
                Return Me.Item + " (C" + FirstChangeset.ToString() + "-C" + LastChangeset.ToString() + ") ( " + NumberOfTimesChanged.ToString + ")"
            Catch ex As Exception
                Return "???"
            End Try
        End Function

    End Class

    Private Sub pbHelp_Click(sender As System.Object, e As System.EventArgs) Handles pbHelp.Click
        Dim msg As String = "Work Item File History " + ControlChars.CrLf + _
                            "The purpose of this module is to find to total effect a work item had on source files." + ControlChars.CrLf + _
                            "" + ControlChars.CrLf + _
                            "A source file can be changed many times by developers through the life of a work item since it is quite common for a work item to go back&forth between a developer, analyst and customer to reach the desired level of perfection for any given task." + ControlChars.CrLf + _
                            "On the other hand a work item might be touching many source files through its life." + ControlChars.CrLf + _
                            "This module shows the total effect a work item had on source control system." + ControlChars.CrLf + _
                            "To accomplish this it goes through all the changesets linked to the work item and lists all the source files these changesets altered. Then it gives you the chance to reach points in each source file's history just before the first touch and just after the last touch of that work item so you can see what was the total change on the source file to accomplish the given task."
        MessageBox.Show(msg, "Work Item File History", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub

    Private Sub btnSelect_Click(sender As System.Object, e As System.EventArgs) Handles btnSelect.Click
        If ModuleHost Is Nothing Then
            Throw New Exception("Module host can not set")
        End If

        Dim configurationServerUri As New Uri(ModuleHost.GetServerAddress)

        Dim configurationServer As New TfsConfigurationServer(configurationServerUri, ModuleHost.GetCredentials())
        Dim tpcService As ITeamProjectCollectionService = configurationServer.GetService(Of ITeamProjectCollectionService)()
        Dim collections = tpcService.GetCollections()
        Dim collection As TfsTeamProjectCollection = configurationServer.GetTeamProjectCollection(collections(0).Id)
        Dim vcs As VersionControlServer = collection.GetService(GetType(VersionControlServer))


        Dim store As New WorkItemStore(collection)

        Dim wiID As Integer = 0
        If TFSWorkItemSelector.SelectWorkItem(store, wiID) Then
            txtWorkItemID.Text = wiID.ToString()
        End If


    End Sub

End Class
